#include "aprs.h"
#include <math.h>

uint16_t aprs_calculatePasscode(const char* call) {
  if (!call || !*call) return 0;
  String root = String(call);
  int dash = root.indexOf('-');
  if (dash > 0) root = root.substring(0, dash);
  root.toUpperCase();
  uint8_t hi = 0x73, lo = 0xE2;
  size_t len = root.length();
  for (size_t i = 0; i < len; i += 2) {
    uint8_t c1 = root.charAt(i);
    uint8_t c2 = (i + 1 < len) ? root.charAt(i + 1) : 0;
    hi ^= c1;
    lo ^= c2;
  }
  return (uint16_t)(((hi & 0x7F) << 8) | lo);
}

String aprs_formatLat(float lat) {
  char buf[16];
  char hemi = (lat >= 0) ? 'N' : 'S';
  lat = fabs(lat);
  int deg = int(lat);
  float min = (lat - deg) * 60.0f;
  snprintf(buf, sizeof(buf), "%02d%05.2f%c", deg, min, hemi);
  return String(buf);
}

String aprs_formatLon(float lon) {
  char buf[16];
  char hemi = (lon >= 0) ? 'E' : 'W';
  lon = fabs(lon);
  int deg = int(lon);
  float min = (lon - deg) * 60.0f;
  snprintf(buf, sizeof(buf), "%03d%05.2f%c", deg, min, hemi);
  return String(buf);
}

bool aprs_sendPosition(WiFiClient &client,
                       const char* callsign,
                       const char* host,
                       uint16_t port,
                       char symTable,
                       char symChar,
                       uint16_t passcode,
                       float lat,
                       float lon,
                       const char* comment) {
  if (!callsign || !host) return false;
  if (!client.connected()) {
    static unsigned long lastFailLog = 0;
    const unsigned long LOG_INTERVAL_MS = 10000;
    if (!client.connect(host, port)) {
      unsigned long now = millis();
      if (now - lastFailLog >= LOG_INTERVAL_MS) {
        Serial.println("[APRS] connect APRS-IS failed");
        lastFailLog = now;
      }
      return false;
    }
    client.printf("user %s pass %u vers ESP32-APRS 1.0\r\n", callsign, passcode);
    Serial.printf("[APRS] login ok (passcode: %u)\n", passcode);
  }
  String commentStr = (comment && comment[0]) ? String(" ") + comment : String(" ESP32 APRS");
  String packet = String(callsign) + ">APRS,TCPIP*:=" +
                  aprs_formatLat(lat) + symTable +
                  aprs_formatLon(lon) + symChar +
                  commentStr;
  client.println(packet);
  Serial.println("[APRS] sent: " + packet);
  return true;
}
